package com.xbongbong.crm.perform.query.list.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.abstracts.AbstractCrmListQryService;
import com.xbongbong.crm.handle.analysis.DefaultListAnalysisDataHandler;
import com.xbongbong.crm.perform.query.list.button.ArchivedTag;
import com.xbongbong.crm.perform.query.list.button.CustomerFocus;
import com.xbongbong.crm.perform.query.list.button.OpportunityFocus;
import com.xbongbong.crm.perform.query.list.button.Remind;
import com.xbongbong.crm.service.condition.OpportunityConditionServiceImpl;
import com.xbongbong.crm.service.impl.OpportunityLinkProductServiceImpl;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.ButtonExtraPojo;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.parent.explain.HandleExplainHelp;
import com.xbongbong.parent.pojo.list.ConditionListPojo;
import com.xbongbong.parent.pojo.list.ConditionListResultPoJo;
import com.xbongbong.parent.pojo.list.DataAnalysisListPojo;
import com.xbongbong.parent.pojo.list.FieldListPojo;
import com.xbongbong.parent.pojo.list.PermissionListPojo;
import com.xbongbong.parent.util.FieldUtil;
import com.xbongbong.pro.applist.pojo.AppListPojo;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.formexplain.pojo.HandleExplainPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.SaleStageEntity;
import com.xbongbong.saas.enums.*;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.dictionary.ArchivedEnum;
import com.xbongbong.saas.help.SaasLinkProductHelp;
import com.xbongbong.saas.help.StageHelp;
import com.xbongbong.saas.model.OpportunityFocusModel;
import com.xbongbong.saas.model.SaleStageModel;
import com.xbongbong.saas.service.toolbox.help.SaasListDataPermissionHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.util.UserPermissionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author 吴峰
 * @Description 机会列表业务层
 * @date 2022/5/23 15:02
 * @Version 1.0
 **/
@Service
@Slf4j
public class OpportunityListServiceImpl extends AbstractCrmListQryService {


    @Resource
    private HandleExplainHelp handleExplainHelp;
    @Resource
    private OpportunityConditionServiceImpl opportunityConditionService;
    @Resource
    private SaasLinkProductHelp saasLinkProductHelp;
    @Resource
    private SaasListDataPermissionHelp saasListDataPermissionHelp;
    @Resource
    private DefaultListAnalysisDataHandler defaultListAnalysisDataHandler;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private OpportunityFocusModel opportunityFocusModel;
    @Resource
    private PushModel pushModel;
    @Resource
    private OpportunityLinkProductServiceImpl opportunityLinkProductService;
    @Resource
    private SaleStageModel saleStageModel;
    @Resource
    private StageHelp stageHelp;
    @Resource
    private Remind remind;
    @Resource
    private OpportunityFocus opportunityFocus;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private PackageHelp packageHelp;


    @Override
    public List<Integer> businessType() {
        return Arrays.asList(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), XbbRefTypeEnum.ALL_OPPORTUNITY.getCode(), XbbRefTypeEnum.KEY_OPPORTUNITY.getCode());
    }

    @Override
    public List<ConditionsEntityExt> getPermission(PermissionListPojo permissionListPojo) throws XbbException {
        UserVO userVO = permissionListPojo.getUserVO();
        List<ConditionsEntityExt> conditionList = new ArrayList<>();

        if (UserPermissionUtil.isMaxDataPermission(userVO, permissionListPojo.getSaasMark(), permissionListPojo.getBusinessType(), permissionListPojo.getDistributorMark(), permissionListPojo.getMenuId(), false)){
            return conditionList;
        }

        return getTeamUserPermission(userVO);
    }

    @Override
    public ConditionListResultPoJo getCondition(ConditionListPojo conditionListPojo) throws XbbException {
        List<ConditionsEntityExt> list = getCommonConditionList(conditionListPojo);
        conditionListPojo.getConditionList().addAll(list);

        // 公共筛选
        webCommonFilter(conditionListPojo);
        return new ConditionListResultPoJo(conditionListPojo.getConditionList(), conditionListPojo.getShouldConditionList());
    }

    private List<ConditionsEntityExt> getCommonConditionList(ConditionListPojo conditionListPojo) throws XbbException {

        List<ConditionsEntityExt> list = opportunityConditionService.handleConditionBySubBusinessType(conditionListPojo);

        conditionListPojo.getConditionList().addAll(list);
        setCommonCondition(conditionListPojo);

        // 关联产品筛选
        saasLinkProductHelp.selectProductCondition(conditionListPojo.getConditionList(), conditionListPojo.getCorpid());

        return conditionListPojo.getConditionList();
    }
    @Override
    public ConditionListResultPoJo mobileGetCondition(ConditionListPojo conditionListPojo) throws XbbException {

        //  手机端条件封装
        saasListDataPermissionHelp.dingtalkRangeScreen(conditionListPojo.getConditionList(), conditionListPojo.getUserVO(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), conditionListPojo.getSubBusinessType(), conditionListPojo.getPlatform());
        // 公共条件封装
        getCommonConditionList(conditionListPojo);
        return new ConditionListResultPoJo(conditionListPojo.getConditionList(), conditionListPojo.getShouldConditionList());
    }

    @Override
    protected void handleFieldAttrEntity(FieldAttrEntity item, FieldListPojo fieldListPojo) {
        super.handleFieldAttrEntity(item, fieldListPojo);
        FieldUtil.packageSelectProductField(item);

    }

    @Override
    public HandleExplainPojo getExplain(FieldListPojo fieldListPojo) throws XbbException {
        List<String> fieldList = new ArrayList<>();
        List<FieldAttrEntity> explainList = commonGetExplain(fieldListPojo, fieldList);
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO(explainList, fieldListPojo.getForm(), fieldListPojo.getCorpid(), fieldListPojo.getUserVO().getUserId(), fieldListPojo.getUserVO(), true, fieldListPojo.getSubBusinessType());
        HandlerExplainVO handlerExplainVO = handleExplainHelp.handleExplain(handlerExplainDTO);
        HandleExplainPojo handleExplainPojo = new HandleExplainPojo();
        explainList = handlerExplainVO.getHeadList();
        handleExplainPojo.setExplainList(explainList);
        handleExplainPojo.setFieldList(fieldList);

        return handleExplainPojo;
    }

    @Override
    public List<PaasFormDataEntityExt> webDataAnalysis(DataAnalysisListPojo dataAnalysisListPojo) throws XbbException {
        try {
            List<PaasFormDataEntityExt> formDataList = dataAnalysisListPojo.getFormDataList();

            FormDataListDTO formDataListDTO = new FormDataListDTO(dataAnalysisListPojo.getCorpid(), dataAnalysisListPojo.getFormId(), dataAnalysisListPojo.getSaasMark(), dataAnalysisListPojo.getBusinessType(), dataAnalysisListPojo.getSubBusinessType(), dataAnalysisListPojo.getDistributorMark(), dataAnalysisListPojo.getUserVO(), dataAnalysisListPojo.getAnalysisAmountOfThousandBitsWithOriginalValue());
            PaasFormDataEsListVO formDataListVO = new PaasFormDataEsListVO();
            formDataListVO.setPaasFormDataESList(formDataList);
            List<FieldAttrEntity> explainList = dataAnalysisListPojo.getExplainList();
            formDataListVO.setHeadList(explainList);
            // 解析关联产品，只有web需要
            opportunityLinkProductService.analysisListProductData(formDataListDTO, formDataListVO.getPaasFormDataESList(), formDataListVO.getHeadList(), 1, null);
            //设置阶段预警颜色部分数据
            stageHelp.setWarningColorData(formDataListDTO, formDataListVO.getPaasFormDataESList(), formDataListVO.getHeadList());
            defaultListAnalysisDataHandler.analysisDataList(formDataListDTO, formDataListVO);
            defaultListAnalysisDataHandler.analysisAmountOfThousandBits(formDataListVO, dataAnalysisListPojo.getAnalysisAmountOfThousandBitsWithOriginalValue());

            return formDataListVO.getPaasFormDataESList();
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            log.error("com.xbongbong.crm.list.OpportunityListServiceImpl.dataAnalysis error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }



    @Override
    public List<AppListPojo> dingtalkOperate(DataAnalysisListPojo dataAnalysisListPojo) throws XbbException {
        String corpid = dataAnalysisListPojo.getCorpid();
        List<AppListPojo> resultList = new ArrayList<>();
        List<PaasFormDataEntityExt> dataList =dataAnalysisListPojo.getFormDataList();
        if (CollectionUtils.isEmpty(dataList)) {
            return resultList;
        }
        Integer businessType = dataAnalysisListPojo.getBusinessType();
        List<Long> dataIdIn = new ArrayList<>();
        dataList.forEach(item->{
            dataIdIn.add(item.getId());
        });
        String userId = dataAnalysisListPojo.getUserId();
        // 关注
        OpportunityFocus focusPojo = opportunityFocus.setFocusField(corpid, userId, dataIdIn, dataAnalysisListPojo.getExplainList());
        Remind remindPojo = remind.setRemindField( corpid, businessType, dataAnalysisListPojo.getSubBusinessType(), dataIdIn, dataAnalysisListPojo.getExplainList());
        Set<String> stageCodeSet = new HashSet<>();
        dataList.forEach(item->{
            JSONObject data = item.getData();
            String stageCode = data.getString(SalesOpportunityEnum.SALE_STAGE.getAttr());
            if (StringUtil.isNotEmpty(stageCode)) {
                stageCodeSet.add(stageCode);
            }
        });
        List<SaleStageEntity> saleStageList = saleStageModel.getByCodeIn(corpid, dataAnalysisListPojo.getFormId(), stageCodeSet);
        Map<String, SaleStageEntity> saleStageMap = new HashMap<>(saleStageList.size());
        saleStageList.forEach(item->{
            saleStageMap.put(item.getCode(), item);
        });
        for (PaasFormDataEntityExt entityExt : dataList) {
            JSONObject data = entityExt.getData();
            Long dataId = entityExt.getDataId();



            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();

            /*-- 角标 -*/
            superScript.put("message", remindPojo.getList().contains(dataId) ? 1 : 0);
            // 关注
            if (focusPojo.getList().contains(dataId)) {
                superScript.put("focus", 1);
            }
            // 归档标志：1代表归档，2代表未归档
            if (Objects.equals(data.getInteger(SalesOpportunityEnum.IS_ARCHIVED.getAttr()), 1)) {
                superScript.put("archived", ArchivedEnum.ARCHIVED.getCode());
            }
            /*-- 其他 -*/
            //格式化钱币
            String estimateAmount = FastJsonHelper.getStringOrDefaultFromFormData(data, SalesOpportunityEnum.ESTIMATE_AMOUNT.getAttr(), "0");
            others.put("amount", estimateAmount);


            List<SummaryDataPoJo> summaryList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.SUMMARY_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            summaryList.forEach(item -> {
                if (Objects.equals(item.getAttr(), SalesOpportunityEnum.ESTIMATE_END_TIME.getAttr())) {
                    if (item.getValue() != null && !item.getValue().isEmpty()) {
                        String estimateTime = (String) item.getValue().get(0);
                        Long estimateEndTime = DateTimeUtil.getInt(estimateTime, DateTimeUtil.SDFDate);
                        if (estimateEndTime < DateTimeUtil.getTodayInt()) {
                            String nameOrCode = data.getString(SalesOpportunityEnum.SALE_STAGE.getAttr());
                            List<Integer> noRemindCode = Arrays.asList(StageTypeEnum.SUCCESS_STAGE.getType(),StageTypeEnum.FAIL_STAGE.getType(),StageTypeEnum.CANCEL_STAGE.getType());
                            SaleStageEntity saleStage = saleStageMap.get(nameOrCode);
                            if(Objects.isNull(saleStage) || !noRemindCode.contains(saleStage.getType())) {
                                // 预计结束时间延期标红
                                item.setStatus("delay");
                            }
                        }
                        return;
                    }
                }
            });
            List<SummaryDataPoJo> lablesList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.LABELS_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);

            List<FormTitlePoJo> titleList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.TITLE_LIST, new JSONArray()).toJavaList(FormTitlePoJo.class);
            //app系统关联数据展示需要 others 和 superScript
            data.put("others", others);
            data.put("superScript", superScript);

            resultList.add(new AppListPojo(dataId, titleList, summaryList, superScript, lablesList, others, entityExt.getAppId(), entityExt.getMenuId(), entityExt.getFormId()));
        }
        return resultList;
    }

    @Override
    public void webOperate(DataAnalysisListPojo dataAnalysisListPojo) throws XbbException {
        List<PaasFormDataEntityExt> dataList =dataAnalysisListPojo.getFormDataList();
        List<FieldAttrEntity> list = dataAnalysisListPojo.getExplainList();
        String corpid = dataAnalysisListPojo.getCorpid();
        String userId = dataAnalysisListPojo.getUserId();
        List<Long> dataIdIn = new ArrayList<>();
        dataList.forEach(item->{
            dataIdIn.add(item.getId());
        });
        // 关注
        CustomerFocus focusPojo = opportunityFocus.setFocusField(corpid, userId, dataIdIn, list);
        // 提醒
        Remind remindPojo = remind.setRemindField( corpid,  dataAnalysisListPojo.getBusinessType(), dataAnalysisListPojo.getSubBusinessType(), dataIdIn, dataAnalysisListPojo.getExplainList());
        String field = SalesOpportunityEnum.SERIAL_NO.getAttr();
        ArchivedTag archivedTagPojo = new ArchivedTag(field+"Tag");
        list.forEach(item->{
            if (Objects.equals(item.getAttr(), field)) {
                item.setTagAttr(field + "Tag");
            }
        });
        Integer businessType = dataAnalysisListPojo.getBusinessType();
        dataList.forEach(item->{
            // 关注
            CustomerFocus.setFocusData(focusPojo, item);
            // 提醒
            Remind.setRemindData(remindPojo, item);
            JSONObject tagData = item.getTagData();
            JSONObject data = item.getData();
            // 设置“归档”状态
            ArchivedTag.setArchivedData(archivedTagPojo, tagData, Objects.equals(businessType, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode()) && Objects.equals(data.getInteger(SalesOpportunityEnum.IS_ARCHIVED.getAttr()), 1), TagEnum.TAG_ARCHIVED);
        });
    }

    @Override
    public List<ButtonPojo> topButton(FormDataListDTO formDataListDTO) throws XbbException {
        try {
            List<ButtonPojo> topButtonList = new ArrayList<>();
            UserVO userVO = formDataListDTO.getLoginUser();
            Long menuId = formDataListDTO.getMenuId();
            String corpid = formDataListDTO.getCorpid();
            Integer subBusinessType = formDataListDTO.getSubBusinessType();
            Set<String> permSet = userVO.getPermSet();
            PaasMenuEntity paasMenuEntity = paasMenuModel.getByKey(menuId, corpid);
            if (Objects.isNull(paasMenuEntity)) {
                return topButtonList;
            }
            List<ListTopButtonEnum> topButtonEnumList = ListTopButtonEnum.getByBusinessType(subBusinessType);
            Integer distributorMark = paasMenuEntity.getDistributorMark();
            for (ListTopButtonEnum topButtonEnum : topButtonEnumList) {
                String permission = topButtonEnum.getProPermissionAlias();
                // permission为1的按钮一直存在的或还没加权限alias
                if (!permSet.contains(permission) && !Objects.equals(permission, StringConstant.POSITIVE_NUMBER)) {
                    continue;
                }
                //销售机会的查重按钮只有旗舰版展示
                Boolean isOpportunityCheck = !packageHelp.isUltimateWithFeeType(corpid)
                        && Objects.equals(topButtonEnum.getProPermissionAlias(), ProPermissionAliasEnum.OPPORTUNITY_DUPLICATE.getAlias());
                if(isOpportunityCheck){
                    continue;
                }
                ButtonPojo buttonPojo = new ButtonPojo();
                BeanUtil.copyProperties(topButtonEnum.getAnEnum(), buttonPojo);
                if (Objects.equals(topButtonEnum.getAnEnum().getAttr(), SaasButtonEnum.IMPORT.getAttr())) {
                    ButtonExtraPojo buttonExtraPojo = new ButtonExtraPojo();
                    buttonExtraPojo.setImportTitle(paasMenuEntity.getName());
                    buttonPojo.setButtonExtra(buttonExtraPojo);
                }
                if (Objects.equals(topButtonEnum.getAnEnum().getAttr(), SaasButtonEnum.EXPORT.getAttr())) {
                    List<ButtonPojo> subButtonList = new ArrayList<ButtonPojo>(){{
                        add(new ButtonPojo(){{BeanUtil.copyProperties(topButtonEnum.getAnEnum(), this);}});
                    }};
                    List<SaasSubButtonEnum> saasSubButtonEnumList = SaasSubButtonEnum.getByPermissionAlias(XbbRefTypeEnum.transferBusinessType4Distributor(formDataListDTO.getSubBusinessType(),formDataListDTO.getDistributorMark()),topButtonEnum,formDataListDTO.getLoginUser().getPermSet());
                    saasSubButtonEnumList.forEach(item->{
                        subButtonList.add(new ButtonPojo(){{setAttr(item.getAlias());setValue(item.getName());}});
                    });
                    buttonPojo.setSubButtons(subButtonList);
                }

                buttonPojo.setDistributorMark(distributorMark);
                topButtonList.add(buttonPojo);
            }
            return topButtonList;
        }catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }
}
